/**********************************************************************************
**
** Copyright (C) 1994 Narvik University College
** Contact: GMlib Online Portal at http://episteme.hin.no
**
** This file is part of the Geometric Modeling Library, GMlib.
**
** GMlib is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** GMlib is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with GMlib.  If not, see <http://www.gnu.org/licenses/>.
**
**********************************************************************************/



/*! \file gmPCannabis.c
 *
 *  Implementation of the PCannabis template class.
 *
 *  \date   2008-09-10
 */


namespace GMlib {


  template <typename T>
  inline
  PCannabis<T>::PCannabis( T size ) {

    _size = size;
    this->_dm = GM_DERIVATION_EXPLICIT;
  }


  template <typename T>
  inline
  PCannabis<T>::PCannabis( const PCannabis<T>& copy ) : PCurve<T>( copy ) {}


  template <typename T>
  PCannabis<T>::~PCannabis() {}


  template <typename T>
  inline
  void PCannabis<T>::eval( T t, int d, bool /*l*/ ) {

    this->_p.setDim( d + 1 );

    this->_p[0][0] = (T) _size * (sin(t)+1)*cos(t)*(9.0/10.0*cos(8*t)+1) * (1.0/10.0*cos(24.0*t)+1) * (1.0/10.0*cos(200*t)+9.0/10.0);
		this->_p[0][1] = (T) _size * sin(t)*(sin(t)+1)*(9.0/10.0*cos(8*t)+1) * (1.0/10.0*cos(24.0*t)+1) * (1.0/10.0*cos(200*t)+9.0/10.0);
    this->_p[0][2] = T(0);

		// BEGIN Latterlig store uttrykk:
    if( this->_dm == GM_DERIVATION_EXPLICIT ) {

      if( d > 0 ) {

        this->_p[1][0] = (T)_size * -20*cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*sin(200*t)
																		 -2.4*cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*sin(24.0*t)*(cos(200*t)/10.0+0.9)
																		 -7.2*cos(t)*(sin(t)+1)*sin(8*t)*(0.1*cos(24.0*t)+1)*(cos(200*t)/10.0+0.9)
																		 -sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
																						*(cos(200*t)/10.0+0.9)
																		 +cos(t)*cos(t)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*(cos(200*t)/10.0+0.9);

        this->_p[1][1] = (T)_size * -20*sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*sin(200*t)
																		-2.4*sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*sin(24.0*t)
																				*(cos(200*t)/10.0+0.9)
																		-7.2*sin(t)*(sin(t)+1)*sin(8*t)*(0.1*cos(24.0*t)+1)
																				*(cos(200*t)/10.0+0.9)
																		+cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
																					 *(cos(200*t)/10.0+0.9)
																		+cos(t)*sin(t)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
																					 *(cos(200*t)/10.0+0.9);
        this->_p[1][2] = T(0);
      }


      if( d > 1 ) {

        this->_p[2][0] = (T)_size * 96.00000000000001*cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*sin(24.0*t)
												*sin(200*t)
												+288.0*cos(t)*(sin(t)+1)*sin(8*t)*(0.1*cos(24.0*t)+1)*sin(200*t)
												+40*sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*sin(200*t)
												-40*cos(t)*cos(t)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*sin(200*t)
												-4000*cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
														 *cos(200*t)
												+34.56000000000001*cos(t)*(sin(t)+1)*sin(8*t)*sin(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												+4.800000000000001*sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*sin(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												-4.800000000000001*cos(t)*cos(t)*(0.9*cos(8*t)+1)*sin(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												-57.60000000000001*cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*cos(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												+14.4*sin(t)*(sin(t)+1)*sin(8*t)*(0.1*cos(24.0*t)+1)
														 *(cos(200*t)/10.0+0.9)
												-14.4*cos(t)*cos(t)*sin(8*t)*(0.1*cos(24.0*t)+1)*(cos(200*t)/10.0+0.9)
												-57.6*cos(t)*(sin(t)+1)*cos(8*t)*(0.1*cos(24.0*t)+1)
														 *(cos(200*t)/10.0+0.9)
												-cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
															 *(cos(200*t)/10.0+0.9)
												-3*cos(t)*sin(t)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
													*(cos(200*t)/10.0+0.9);
        this->_p[2][1] = (T)_size * 96.00000000000001*sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*sin(24.0*t)
                        *sin(200*t)
												+288.0*sin(t)*(sin(t)+1)*sin(8*t)*(0.1*cos(24.0*t)+1)*sin(200*t)
												-40*cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*sin(200*t)
												-40*cos(t)*sin(t)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*sin(200*t)
												-4000*sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
														 *cos(200*t)
												+34.56000000000001*sin(t)*(sin(t)+1)*sin(8*t)*sin(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												-4.800000000000001*cos(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*sin(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												-4.800000000000001*cos(t)*sin(t)*(0.9*cos(8*t)+1)*sin(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												-57.60000000000001*sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*cos(24.0*t)
																					*(cos(200*t)/10.0+0.9)
												-14.4*cos(t)*(sin(t)+1)*sin(8*t)*(0.1*cos(24.0*t)+1)
														 *(cos(200*t)/10.0+0.9)
												-14.4*cos(t)*sin(t)*sin(8*t)*(0.1*cos(24.0*t)+1)*(cos(200*t)/10.0+0.9)
												-57.6*sin(t)*(sin(t)+1)*cos(8*t)*(0.1*cos(24.0*t)+1)
														 *(cos(200*t)/10.0+0.9)
												-sin(t)*sin(t)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*(cos(200*t)/10.0+0.9)
												-sin(t)*(sin(t)+1)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)
															 *(cos(200*t)/10.0+0.9)
												+2*cos(t)*cos(t)*(0.9*cos(8*t)+1)*(0.1*cos(24.0*t)+1)*(cos(200*t)/10.0+0.9);
        this->_p[2][2] = T(0);
      }
    }
  }


  template <typename T>
  inline
  T PCannabis<T>::getEndP() {

    return T( M_PI * 2.0 );
  }


  template <typename T>
  inline
  std::string PCannabis<T>::getIdentity() const {

    return "PCannabis";
  }


  template <typename T>
  inline
  T PCannabis<T>::getStartP() {

    return T(0);
  }


  template <typename T>
  inline
  bool PCannabis<T>::isClosed() const {

    return true;
  }
}
